﻿using Microsoft.Extensions.Caching.Memory;
using System.Security.Cryptography;
using System.Text;
using WxProxy.Model;

namespace WxProxy.Services
{
    public class WxJsSdkService
    {
        private readonly IConfiguration _config;
        private readonly IMemoryCache _cache;
        private readonly HttpClient _http;

        public WxJsSdkService(IConfiguration config, IMemoryCache cache, IHttpClientFactory factory)
        {
            _config = config;
            _cache = cache;
            _http = factory.CreateClient();
        }

        private string AppId => _config["WeChat:AppId"]!;
        private string AppSecret => _config["WeChat:AppSecret"]!;

 
            /// <summary>
            /// 获取微信 JS-SDK 配置参数
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public async Task<WXConfigDto> GetJsConfigAsync(string url)
            {
                var ticket = await GetJsApiTicketAsync();
                var nonceStr = Guid.NewGuid().ToString("N");
                var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

                var plain = $"jsapi_ticket={ticket}&noncestr={nonceStr}&timestamp={timestamp}&url={url}";
                var sha1 = SHA1.HashData(Encoding.UTF8.GetBytes(plain));
                var signature = string.Concat(sha1.Select(b => b.ToString("x2")));

                return new WXConfigDto
                {
                    AppId = AppId,
                    Timestamp = timestamp,
                    NonceStr = nonceStr,
                    Signature = signature
                };
            }

        private async Task<string> GetAccessTokenAsync()
        {
            if (_cache.TryGetValue("wx:access_token", out string token)) return token;

            var url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={AppId}&secret={AppSecret}";
            var json = await _http.GetStringAsync(url);
            var data = System.Text.Json.JsonDocument.Parse(json);
            try
            {
                token = data.RootElement.GetProperty("access_token").GetString()!;
            }
            catch
            {
                throw new Exception(json);
            }

            _cache.Set("wx:access_token", token, TimeSpan.FromMinutes(110));
            return token;
        }

        private async Task<string> GetJsApiTicketAsync()
        {
            if (_cache.TryGetValue("wx:jsapi_ticket", out string ticket)) return ticket;

            var token = await GetAccessTokenAsync();
            var url = $"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={token}&type=jsapi";
            var json = await _http.GetStringAsync(url);
            var data = System.Text.Json.JsonDocument.Parse(json);
            ticket = data.RootElement.GetProperty("ticket").GetString()!;

            _cache.Set("wx:jsapi_ticket", ticket, TimeSpan.FromMinutes(110));
            return ticket;
        }


    }
}
